package civicinity.ist.psu.edu;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONException;
import org.json.JSONObject;

import com.facebook.android.AsyncFacebookRunner;
import com.facebook.android.DialogError;
import com.facebook.android.Facebook;
import com.facebook.android.Facebook.DialogListener;
import com.facebook.android.FacebookError;
import com.facebook.android.Util;

import civicinity.ist.psu.edu.constants.Constants;
import civicinity.ist.psu.edu.facebook.BaseRequestListener;
import civicinity.ist.psu.edu.facebook.SessionStore;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Looper;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class CivicinityLogin extends Activity {
	
	private Facebook mFacebook;
	private AsyncFacebookRunner mAsyncRunner;
	
	private ProgressDialog mDialog = null;
	private EditText mTextUsername;
	private EditText mTextPassword;
	private int mPreviousActivity;
	private String mUsername;
	private String mPassword;
	private boolean mLoginValid = false;
	
	private SharedPreferences mPref;
	
	@Override
	public void onCreate(Bundle savedInstanceState){
		super.onCreate(savedInstanceState);
		setContentView(R.layout.login);
		
		mFacebook = new Facebook(Constants.FACEBOOK_APP_ID);
		mAsyncRunner = new AsyncFacebookRunner(mFacebook);
		
		mTextUsername = (EditText)findViewById(R.id.username_text);
		mTextPassword = (EditText)findViewById(R.id.password_text);
		
		//Define Preferences to store username and password
		mPref = PreferenceManager.getDefaultSharedPreferences(this);

		//Login button
		Button buttonLogin = (Button)findViewById(R.id.login_button);
		buttonLogin.setOnClickListener(new View.OnClickListener(){
			public void onClick(View v){
				mUsername = mTextUsername.getText().toString().trim();
				mPassword = mTextPassword.getText().toString().trim();
				
				if(mUsername.equals("") || mPassword.equals("")){
					Toast.makeText(CivicinityLogin.this, "Username and/or password not recognized. Please check and try again.",Toast.LENGTH_SHORT).show();	
				}else{
					new AsyncLogin().execute();
				}
			}
		}		
		);
		
		Button fbButtonLogin = (Button)findViewById(R.id.fb_login_button);
		fbButtonLogin.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				
				mFacebook.authorize(CivicinityLogin.this, new String[] {"offline_access", "email", "read_stream"}, new DialogListener(){

					@Override
					public void onComplete(Bundle values) {
						// TODO Auto-generated method stub
				
						// Login success and save user's profile
			        	if(Looper.myLooper() == null) {
			        		Looper.prepare();
			        	}
			        	
			        	mDialog = ProgressDialog.show(CivicinityLogin.this, "Loading...", "Logging into Civicinity mobile application...", true);
						
						mAsyncRunner.request("me", new SampleRequestListener());
						
						
						
					}

					@Override
					public void onFacebookError(FacebookError e) {
						// TODO Auto-generated method stub
						e.printStackTrace();
					}

					@Override
					public void onError(DialogError e) {
						// TODO Auto-generated method stub
						e.printStackTrace();
					}

					@Override
					public void onCancel() {
						// TODO Auto-generated method stub
						
					}
					
				});
			}
		});
		
		//Test login button
		Button buttonTestLogin = (Button)findViewById(R.id.test_login_button);
		buttonTestLogin.setOnClickListener(new View.OnClickListener(){
			public void onClick(View v){
				guestLoginDialog();
			}
		});
		
		//Sign up button
		Button buttonSignUp = (Button)findViewById(R.id.signup_button);
		buttonSignUp.setOnClickListener(new View.OnClickListener(){
			public void onClick(View v){
				//Make intent web browser for sign up
				Toast.makeText(CivicinityLogin.this, "Coming soon!", Toast.LENGTH_SHORT).show();
				//Intent intent = new Intent (Intent.ACTION_VIEW);
				//intent.setData(Uri.parse(getString(R.string.signupURL)));
				//startActivity(intent);
			}
		});
	}
	
    public class SampleRequestListener extends BaseRequestListener {

        public void onComplete(final String response, final Object state) {

    		
            // then post the processed result back to the UI thread
            // if we do not do this, an runtime exception will be generated
            // e.g. "CalledFromWrongThreadException: Only the original
            // thread that created a view hierarchy can touch its views."
            CivicinityLogin.this.runOnUiThread(new Runnable() {
                public void run() {
    	    		// create the account from our database based on the username
    	    		// so far the password is randomly generated.
    	    		// or we can ask the user to put the username or password. (it is like creating the new account from our system)
    	    		// TODO: connect to our local server.
                	// process the response here: executed in background thread
                    Log.d("Facebook-Example", "Response: " + response.toString());
                    JSONObject json;
                    String name = "";
					try {
						json = Util.parseJson(response);
						name = json.getString("name");  
					} catch (JSONException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (FacebookError e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
                      	
					SessionStore.save(mFacebook, CivicinityLogin.this);
                	
                    // save the username into the sharedpreferences
                    SharedPreferences.Editor editor = mPref.edit();
    				editor.putString("username", name);
    				editor.putInt("user_id", 1); // temporary put id as "admin" (id=1) TODO : not decided what to do yet.
    				editor.putString("password", name); // temporaray put password as sme as username TODO : need to do something later.
    				editor.putBoolean("loggedin", true);
    	    		editor.putBoolean("guest_mode", false);
    	    		editor.putBoolean("facebook", true);
    	    		editor.commit();
    	    		
    				startActivity(new Intent(CivicinityLogin.this, CivicinityMainpage.class));
    				
    				finish();
                }
            });
            
            mDialog.dismiss();
            
            // ask something...
            //new syncWithLocalDatabase().execute();
        }
    }
    
    /* 
    class syncWithLocalDatabase extends AsyncTask<Void, Void, Void> {

		protected void onPreExecute() {
			mDialog = ProgressDialog.show(CivicinityLogin.this, "Loading...", "Authenticating with the local server...", true);
		}
		
		@Override
		protected Void doInBackground(Void... arg0) {
			
			HttpClient httpClient = new DefaultHttpClient();
			HttpPost httpPost = new HttpPost(Constants.USER_LOGIN + "?username=" + mUsername + "&password=" + mPassword);
			String result = "";
			
			try {
				HttpResponse response = httpClient.execute(httpPost);
				
				if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
					BufferedReader br = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
					
					StringBuilder result_str = new StringBuilder();
					for(;;){
						String line = br.readLine();
						if (line == null) 
							break;
						result_str.append(line+'\n');
					}
					result = result_str.toString();
					JSONObject jsonobj = new JSONObject(result);
					
					if(jsonobj.getBoolean("success") == false){
						mLoginValid = false;
					}
					else {
						mLoginValid = true;
						
						// update the sharedpreference values
						SharedPreferences.Editor editor = mPref.edit();
						editor.putString("username", mUsername.trim());
						editor.putString("password", mPassword.trim());
						editor.putBoolean("loggedin", true);
			    		editor.putBoolean("guest_mode", false);
			    		editor.putBoolean("facebook", false);
			    		editor.putInt("user_id", jsonobj.getInt("success_message"));
			    		editor.commit();
			
			    		finish();
			    		
			    		// when logging-in successfully, move to the mainpage.
						startActivity(new Intent(CivicinityLogin.this, CivicinityMainpage.class));
					}
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			// TODO Auto-generated method stub
			return null;
		}
		
		protected void onPostExecute(Void unused) {
			mDialog.dismiss();
		}
    }
    */
    		
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        mFacebook.authorizeCallback(requestCode, resultCode, data);
    }
	
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		super.onKeyDown(keyCode, event);
	    if (keyCode == KeyEvent.KEYCODE_BACK) {
	        //stopService(new Intent(PBBLogin.this, HelperBackgroundService.class));
	        finish();
	        return true;
	    }
	    return false;
	}
	
	public void guestLoginDialog() {
		new AlertDialog.Builder(CivicinityLogin.this)
		.setTitle("Guest login")
		.setMessage("In the Guest mode, you will access any information on events or shares, but are not able to upload your data to the server.")
		.setPositiveButton("Login", new DialogInterface.OnClickListener() {
			
			@Override
			public void onClick(DialogInterface dialog, int which) {
				// TODO Auto-generated method stub
				
				SharedPreferences.Editor editor = mPref.edit();
				editor.putString("username", "Guest");
				editor.putString("password", "Guest");
				editor.putBoolean("loggedin", true);
	    		editor.putBoolean("guest_mode", true);
	    		editor.putBoolean("facebook", false);
	    		editor.commit();
								
				startActivity(new Intent(CivicinityLogin.this, CivicinityMainpage.class));
				
				finish();
			}
		})
		.setNegativeButton("Back", new DialogInterface.OnClickListener() {
			
			@Override
			public void onClick(DialogInterface dialog, int which) {
				// TODO Auto-generated method stub
				// nothing to do
			}
		})
		.show();
	}	
	
	/**
	 * Async class for the login process
	 */
	class AsyncLogin extends AsyncTask<String, Integer, Void> {
		
		protected void onPreExecute() {
			mDialog = ProgressDialog.show(CivicinityLogin.this, "Loading...", "Logging into Civicinity mobile application...", true);
		}
		@Override
		protected Void doInBackground(String... url) {
			
			HttpClient httpClient = new DefaultHttpClient();
			HttpPost httpPost = new HttpPost(Constants.USER_LOGIN + "?username=" + mUsername + "&password=" + mPassword);
			String result = "";
			
			try {
				HttpResponse response = httpClient.execute(httpPost);
				
				if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
					BufferedReader br = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
					
					StringBuilder result_str = new StringBuilder();
					for(;;){
						String line = br.readLine();
						if (line == null) 
							break;
						result_str.append(line+'\n');
					}
					result = result_str.toString();
					JSONObject jsonobj = new JSONObject(result);
					
					if(jsonobj.getBoolean("success") == false){
						mLoginValid = false;
					}
					else {
						mLoginValid = true;
						
						// update the sharedpreference values
						SharedPreferences.Editor editor = mPref.edit();
						editor.putString("username", mUsername.trim());
						editor.putString("password", mPassword.trim());
						editor.putBoolean("loggedin", true);
			    		editor.putBoolean("guest_mode", false);
			    		editor.putBoolean("facebook", false);
			    		editor.putInt("user_id", jsonobj.getInt("success_message"));
			    		editor.commit();
			
			    		finish();
			    		
			    		// when logging-in successfully, move to the mainpage.
						startActivity(new Intent(CivicinityLogin.this, CivicinityMainpage.class));
					}
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			// TODO Auto-generated method stub
			return null;
		}
		
		protected void onPostExecute(Void unused) {
			if(!mLoginValid) {
				Toast.makeText(CivicinityLogin.this, "Incorrect Username/Password. Please try again.", Toast.LENGTH_SHORT).show();
			}
			mDialog.dismiss();
		}
	}
}
